﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyCoreLib.Data.Common
{
    public abstract class DbTransactionObject : DisposableBase, IDbTransactionObject
    {
        internal event Action Disposed;
        internal event Action Commiting;
        internal event Action Committed;
        internal event Action RolledBack;
        

        internal readonly IDbTransaction Transaction;

        private readonly DbClientObject ConnectionObject;

        internal protected DbTransactionObject(DbClientObject connection, IDbTransaction transaction)
        {
            ConnectionObject = connection;
            Transaction = transaction;
        }


        protected override void Dispose(bool disposing)
        {
            try
            {
                base.Dispose(disposing);
            }
            finally
            {
                Invoke(Disposed, ()=> Disposed = null);                 
            }            
        }

        public void Commit()
        {
            ThrowIfDisposed();
            try
            {
                this.Transaction.Commit();
            }
            finally
            {
                Invoke(Committed, () => Committed = null);               
            }
        }

        public void Rollback()
        {
            ThrowIfDisposed();
            try
            {
                this.Transaction.Commit();
            }
            finally
            {
                Invoke(RolledBack, () => RolledBack = null);
            }
        }

        private void Invoke(Action action, Action onCompleted)
        {
            try
            {
                if (action != null)
                {
                    action();
                }
            }
            finally
            {
                if (onCompleted != null)
                {
                    onCompleted();
                }
            }
        }

        public IDbClientObject Connection
        {
            get
            {
                ThrowIfDisposed();
                return this.Connection;
            }
        }

        public System.Data.IsolationLevel IsolationLevel
        {
            get
            {
                ThrowIfDisposed();
                return this.Transaction.IsolationLevel;
            }
        }
    }
}
